#pragma once
#include "noncopyable.h"
#include "InetAddress.h"
#include "Callbacks.h"
#include "Buffer.h"
#include "Timestamp.h"

#include <memory>
#include <string>
#include <atomic>
#include <string>

class Channel;
class EventLoop;
class Socket;
/**
 * TcpServer => Acceptor => 有一个新用户连接，通过accept函数拿到connfd
 * =》TcpConnection 设置回调=》Channel =》Poller =》channel的回调操作
 */
class TcpConnection : noncopyable,public std::enable_shared_from_this<TcpConnection>
{

public:
    TcpConnection(EventLoop *loop,
                const std::string&name,
                int sockfd,
                const InetAddress& localAddr,
                const InetAddress& peerAddr);
    ~TcpConnection();
    EventLoop* getLoop() const { return loop_;}
    const std::string& name() const {return name_;}
    const InetAddress& localAddress() const { return localAddr_;}
    const InetAddress& peerAddress() const { return peerAddr_;}
    bool connected() const { return state_ == kConnected; }
    bool disconnected() const { return state_ == kDisconnected; }
    void send(const std::string &buf);
    // void send(const StringPiece& message);
    // void send(Buffer *message);
    // 关闭当前连接
    void shutdown();
    void setConnectionCallback(const ConnectionCallback& cb)
    {connectionCallback_ = cb;}

    void setMessageCallback(const MessageCallback& cb)
    {messageCallback_ = cb;}

    void setWriteCompleteCallback(const WriteCompleteCallback& cb)
    {writeCompleteCallback_ = cb;}

    void setHighWaterMarkCallback(const HighWaterMarkCallback& cb,size_t highWaterMark)
    {highWaterMarkCallback_ = cb;highWaterMark_ = highWaterMark;}
    
    void setCloseCallback(const CloseCallback& cb)
    {closeCallback_ = cb;}

    // 连接建立
    void connectEstablished();
    void connectDestroyed();

private:
    enum State { kDisconnected, kConnecting, kConnected, kDisconnecting };
    void setState(State state) {state_ = state;}
    void handleRead(Timestamp receiveTime);
    void handleWrite();
    void handleClose();
    void handleError();

    void sendInLoop(const void* message,size_t len);
    void shutdownInLoop();

    EventLoop *loop_;// TcpConnection 都是在subLoop里面管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;
    
    std::unique_ptr <Socket> socket_;
    std::unique_ptr <Channel> channel_;
    
    const InetAddress localAddr_;
    const InetAddress peerAddr_;

    ConnectionCallback connectionCallback_;//有新连接时的回调
    MessageCallback messageCallback_;//有读写消息的回调
    WriteCompleteCallback writeCompleteCallback_;//消息发送完成以后的回调
    CloseCallback closeCallback_;
    HighWaterMarkCallback highWaterMarkCallback_;
    
    size_t highWaterMark_;
    
    Buffer inputBuffer_;
    Buffer outputBuffer_;
};



